package com.kaguya.vams.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kaguya.vams.common.constant.HttpStatus;
import com.kaguya.vams.domain.Result;
import com.kaguya.vams.domain.dto.SysMenuDto;
import com.kaguya.vams.domain.entity.SysMenu;
import com.kaguya.vams.domain.entity.SysRoleMenu;
import com.kaguya.vams.domain.entity.SysUser;
import com.kaguya.vams.utils.MapUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Delete;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.Arrays;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author kaguya
 * @since 2021-07-28
 */
@Slf4j
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController extends BaseController {

    /**
     * 获取导航栏信息以及权限集合
     *
     * @return
     */
    @GetMapping("/nav")
    public Result getNav(Principal principal) {
        log.info("获取导航菜单- ");
        String username = principal.getName();
        SysUser user = userService.getUserByUserName(username);

        //获取权限信息
        String userAuthorities = userService.getUserAuthorities(user.getId());
        //工具类通过分隔符转换成数组
        String[] authorities = StringUtils.tokenizeToStringArray(userAuthorities, ",");

        //获取导航栏信息
        List<SysMenuDto> menuList = menuService.getCurrentUserNav();

        //返回数据
        return Result.ok(
                MapUtils.build()
                        .put("authorities", authorities)
                        .put("nav", menuList)
        );
    }

    /**
     * 获取菜单列表
     *
     * @return
     */
    @PreAuthorize("hasAuthority('sys:menu:list')")
    @GetMapping("/list")
    public Result list() {
        //返回带子节点的菜单列表
        List<SysMenu> list = menuService.getMenuList();
        return Result.ok(list);
    }

    /**
     * 新增菜单信息
     *
     * @return
     */
    @PreAuthorize("hasAuthority('sys:menu:save')")
    @PostMapping("/save")
    public Result save(@RequestBody SysMenu menu) {
        //新增初始值 创建时间 修改时间 通过实体类mp自动填充
        boolean save = menuService.save(menu);
        log.info("新增" + (save == true ? "成功" : "失败"));
        return Result.ok();
    }

    /**
     * 根据id修改菜单信息
     *
     * @return
     */
    @PreAuthorize("hasAuthority('sys:menu:update')")
    @PutMapping("/update")
    public Result update(@Validated @RequestBody SysMenu menu) {

        boolean update = menuService.updateById(menu);

        //修改后，清除与其关联的权限缓存
        userService.clearUserAuthorityInfoByMenuId(menu.getId());

        log.info("修改" + (update == true ? "成功" : "失败"));

        return update == true ? Result.ok() : Result.fail();
    }

    /**
     * 根据id删除菜单信息
     *
     * @return
     */
    @PreAuthorize("hasAuthority('sys:menu:delete')")
    @DeleteMapping("/delete/{rowId}")
    public Result delete(@PathVariable Long rowId) {

        //首先判断是否有子集，如果有子集，不允许删除
        int hasChild = menuService.count(new QueryWrapper<SysMenu>().eq("parent_id", rowId));
        if (hasChild > 0) {
            return Result.msg(HttpStatus.FAIL.getCode(), "请先删除子节点！");
        }

        //删除菜单
        boolean MenuFlag = menuService.removeById(rowId);

        //删除后，清除与其关联的权限缓存
        userService.clearUserAuthorityInfoByMenuId(rowId);

        //如果该菜单在关联表中有数据，删除关联表数据
        boolean RMFlag = true;
        int hasMenuInRM = roleMenuService.count(new QueryWrapper<SysRoleMenu>().eq("menu_id", rowId));
        if(hasMenuInRM > 0) {
            RMFlag = roleMenuService.removeById(rowId);
        }

        if (MenuFlag && RMFlag) {
            log.info("删除成功");
        } else {
            log.info("删除失败");
        }
        return Result.ok();
    }

    /**
     * 根据id查看单条菜单信息
     *
     * @return
     */
    @GetMapping("/info/{rowId}")
    public Result info(@PathVariable Long rowId) {
        //菜单基本信息
        SysMenu menu = menuService.getOne(new QueryWrapper<SysMenu>().eq("id", rowId));

        //菜单上级id的名称 父id 0 代表自身为根目录
        SysMenu parent = new SysMenu();
        parent.setName("根目录");
        if(menu.getParentId() != 0){
            parent = menuService.getById(menu.getParentId());
        }

        return Result.ok(
                MapUtils.build()
                .put("menu",menu)
                .put("parentName",parent.getName())
        );
    }
}
